import random
from BlockChain import Blockchain
from Wallet import Wallet

blockchain = Blockchain()


class Network(object):

    def __init__(self):
        self.peers = set()
        self.off_peers = []

    def create_genesis_block(self):  # part 1
        blockchain.create_genesis_block()
        return blockchain.chain[0]

    def add_peer(self, host, port):  # part 2
        peer_name = f"{host}:{port}"
        self.peers.add(peer_name)
        return peer_name

    def login(self, peer):  # part 3
        peer.online = True
        self.off_peers = [p for p in self.off_peers if p != peer.peerName]
        self.peers.add(peer.peerName)
        return True

    def logout(self, peer):  # part 4
        peer.online = False
        if peer.peerName in self.peers:
            self.peers.remove(peer.peerName)
        if peer.peerName not in self.off_peers:
            self.off_peers.append(peer.peerName)
        return True

    def peer_online(self):  # part 5
        return list(self.peers)


    def create_peer(self, peer):
        peer.pid = self.nop
        peer.wallet.generate_keys()
        self.peers.append(peer)

    def generate_random_peer(self, n):
        host = '127.0.0.1'
        for i in range(5):
            port = random.randint(5001, 9000)
            self.add_peer(host, port)
        return self.peers


class Peer:
    def __init__(self, name=None):  # 节点初始化函数
        self.online = False
        self.peerName = name
        self.chain = []
        self._is_wallet_generated = False
        self.generate_wallet()

    def generate_wallet(self):  # 用于节点生成钱包对象
        if not self._is_wallet_generated:
            self.wallet = Wallet()
            self._is_wallet_generated = True

    '''
    节点区块链同步函数。
    用于节点与网络之间的区块链进行数据同步。
    '''

    def syn_blockchain(self, blockchain):  # TODO part 6
        self.chain = blockchain.get_chain()
        return True

    def print_blockchain(self):  # 输出节点的区块链副本数据
        print("本节点区块链包含区块个数: %d" % len(self.chain))
        for block in self.chain:
            print("区块索引：%s" % block['index'])
            print("上个区块哈希：%s" % block['previous_hash'])
            print("区块交易信息：%s" % block['transactions'])
            print("本区块哈希：%s" % block['hash'])
            print("===========================================================================\n")

    '''
    节点版本的交易函数。
    用于节点之间发送交易数据。交易需要后续挖矿来确认从而产生新的区块。
    '''

    def send_transaction(self, sender, receiver, tx_data):  # TODO part 7
        message = json.dumps({
            'sender': sender,
            'receiver': receiver,
            'data': tx_data,
            'timestamp': time.time()
        })
        signature = self.wallet.signature(message)
        return True
